﻿using System;
using System.Xml.Linq;
using System.Xml.Serialization;
using DACU.Player.Enums;
using Un4seen.Bass;

namespace DACU.Tools
{
	[Serializable]
	public class ConfigFile
	{
		[Serializable]
		public class PlaylistNode
		{
			[Serializable]
			public class TrackNode
			{
				private int _id;
				[XmlAttribute(AttributeName = "Id")]
				public int Id
				{
					get { return _id; }
					set { _id = value; }
				}

				private double _lastPosition;
				[XmlAttribute(AttributeName = "Position")]
				public double LastPosition
				{
					get { return _lastPosition; }
					set { _lastPosition = value; }
				}

				private BASSActive _lastState;
				[XmlAttribute(AttributeName = "State")]
				public BASSActive LastState
				{
					get { return _lastState; }
					set { _lastState = value; }
				}

				private TrackType _lastTrackType;
				[XmlAttribute(AttributeName = "Type")]
				public TrackType LastTrackType
				{
					get { return _lastTrackType; }
					set { _lastTrackType = value; }
				}

				public T ToXml<T>()
				{
					var elem = new XElement("Track",
						new XAttribute("Id",Id),
						new XAttribute("Position",LastPosition),
						new XAttribute("State",LastState),
						new XAttribute("Type",LastTrackType)
						);
					if (typeof(T) == typeof(XElement) || typeof(T) == typeof(string))
						return (T)Convert.ChangeType(elem,typeof(T));
					return default(T);
				}

				public static TrackNode FromXml(XElement element)
				{
					if (element == null || element.IsEmpty) return new TrackNode();
					var track = new TrackNode
					            	{
					            		Id = element.GetIntFromAttribute("Id"),
					            		LastPosition = element.GetDoubleFromAttribute("Position"),
					            		LastState = element.GetBASSActiveFromAttribute("State"),
					            		LastTrackType = element.GetTrackTypeFromAttribute("Type")
					            	};
					return track;
				}
			}

			private string _lastPlayList;
			[XmlAttribute(AttributeName = "Last")]
			public string LastPlayList
			{
				get { return _lastPlayList; }
				set { _lastPlayList = value; }
			}

			private TrackNode _track = new TrackNode();
			[XmlElement(ElementName = "Track")]
			public TrackNode Track
			{
				get { return _track; }
				set { _track = value; }
			}

			public T ToXml<T>()
			{
				var elem = new XElement("Playlist",
					new XAttribute("Last", LastPlayList??""),
					Track.ToXml<XElement>()
					);
				if (typeof(T) == typeof(XElement) || typeof(T) == typeof(string))
					return (T)Convert.ChangeType(elem, typeof(T));
				return default(T);
			}

			public static PlaylistNode FromXml(XElement element)
			{
				if (element == null || element.IsEmpty) return new PlaylistNode();
				var playlistNode = new PlaylistNode
				                   	{
				                   		LastPlayList = element.GetStringFromAttribute("Last"),
				                   		Track = TrackNode.FromXml(element.Element("Track"))
				                   	};
				return playlistNode;
			}
		}
		private float _volume;
		[XmlAttribute(AttributeName = "Volume")]
		public float Volume
		{
			get { return _volume; }
			set { _volume = value; }
		}

		private bool _isShuffle;
		[XmlAttribute(AttributeName = "Shuffle")]
		public bool IsShuffle
		{
			get { return _isShuffle; }
			set { _isShuffle = value; }
		}

		private bool _isFileLoop;
		[XmlAttribute(AttributeName = "FileLoop")]
		public bool IsFileLoop
		{
			get { return _isFileLoop; }
			set { _isFileLoop = value; }
		}

		private bool _isListLoop;
		[XmlAttribute(AttributeName = "ListLoop")]
		public bool IsListLoop
		{
			get { return _isListLoop; }
			set { _isListLoop = value; }
		}

		private PlaylistNode _playlist = new PlaylistNode();
		[XmlElement(ElementName = "Playlist")]
		public PlaylistNode Playlist
		{
			get { return _playlist; }
			set { _playlist = value; }
		}

		public T ToXml<T>()
		{
			var elem = new XElement("ConfigFile",
				//new XAttribute("xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance"),
				//new XAttribute("xmlns:xsd","http://www.w3.org/2001/XMLSchema"),
				new XAttribute("Volume", Volume),
				new XAttribute("Shuffle", IsShuffle),
				new XAttribute("FileLoop", IsFileLoop),
				new XAttribute("ListLoop", IsListLoop),
				Playlist.ToXml<XElement>()
				);
			if (typeof(T) == typeof(XElement) || typeof(T) == typeof(string))
				return (T)Convert.ChangeType(elem, typeof(T));
			return default(T);
		}

		public static ConfigFile FromXml(XElement element)
		{
			if (element == null || element.IsEmpty) return new ConfigFile();
			var configFile = new ConfigFile
			{
				Volume = element.GetFloatFromAttribute("Volume"),
				IsShuffle = element.GetBoolFromAttribute("Shuffle"),
				IsFileLoop = element.GetBoolFromAttribute("FileLoop"),
				IsListLoop = element.GetBoolFromAttribute("ListLoop"),
				Playlist = PlaylistNode.FromXml(element.Element("Playlist"))
			};
			return configFile;
		}
	}
}
